<?php

namespace app\service;

use app\model\DelayOrderTaskModel;
use app\model\EntityModel;
use app\model\ProjectMemberModel;
use app\tool\SingletonTrait;

class DelayOrderService
{
    use SingletonTrait;
    private DelayOrderTaskModel $delayOrderTaskModel;
    private EntityModel $entityModel;
    private ProjectMemberModel  $projectMemberModel;

    private OptionsService $optionsService;

    public function __construct()
    {
        $this->delayOrderTaskModel = new DelayOrderTaskModel();
        $this->entityModel = new EntityModel();
        $this->projectMemeberModel = new ProjectMemberModel();
        $this->optionsService = OptionsService::getInstance();
    }

    /**
     *  环节待确认统计
     *  延期单未审核
     *  延期单任务制片未确认  环节未确认
     *  延期单任务环节状态是已激活待确认状态
     * @param int $projectId
     * @param string $episodeId
     * @param string $userId
     * @param string $waitForMeToConfirm
     * @param array $dateSearch
     * @return array
     */
    public function stepCategoryWaitConfirmCount(int $projectId, string $episodeId, string $userId,string $waitForMeToConfirm,array $dateSearch): array
    {
        $stepCategoryList = $this->optionsService->getProjectShowStepCategoryListConfig($projectId);
        $optionsConfig = $this->optionsService->getOptionsData('project_team_config');
        if(empty($optionsConfig) || empty($optionsConfig)){
            return [];
        }
        $stepCategoryConfig = array_filter($optionsConfig, fn($item) => $item['status'] == 1);
//        $stepCategoryId = array_merge(...array_column($stepCategoryConfig, 'step_category_id'));
        //我是制片数据确认
        $projectMemberData = $this->checkWithForMeConfig($projectId, $userId);
        $where = "";
        if(!empty($projectMemberData)){
            $where = "dot.confirm_status = 'producer_confirming'";
        }
        //我能确认的环节数据
        $waitForMeToConfirmStepCategoryId = $this->canForMeConfirmStepCategoryId($projectId);
        if(!empty($waitForMeToConfirmStepCategoryId)){
            $stepCategoryIds = implode(',', $waitForMeToConfirmStepCategoryId);
            if(!empty($where)){
                $where .= " or ";
            }
            $where .= "(dotscc.step_category_id in ({$stepCategoryIds}) and dot.confirm_status = 'step_category_confirming' and is_active = 'yes')";
        }
        $dbr = $this->delayOrderTaskModel
            ->alias('dot')
            ->join('delay_order_task_step_category_confirm dotscc', 'dotscc.delay_order_task_id = dot.id','left')
            ->where('dot.project_id', $projectId)
            ->whereRaw($where)
            ->field('if(dot.confirm_status = "producer_confirming", dot.step_category_id, dotscc.step_category_id) field_step_category_id, count(distinct dot.id) num')
            ->group('field_step_category_id');

        if(!empty($episodeId)){
            $dbr = $dbr->where(['dot.episode_id' => $episodeId]);
        }

        if (!empty($dateSearch)) {
            $dbr = $dbr->whereBetween('dot.created', $dateSearch);
        }
        $dc = $dbr->select();


        $dc = $dc->column('num', 'field_step_category_id');
        $res = [];
        foreach ($stepCategoryConfig as $value){
            $count = 0;
            // 过滤掉没有的环节
//            $temp = array_filter($dc, fn($v, $k) => in_array($k, $value['step_category_id']), ARRAY_FILTER_USE_BOTH);
//            $count += array_sum($temp);
            $tmp = array_filter($stepCategoryList, fn($v) => in_array($v['id'], $value['step_category_id']));
            $children = [];
            foreach ($tmp as $stepCategory) {
                $count += $dc[$stepCategory['id']] ?? 0;
                $children[] = [
                    'id' => $stepCategory['id'],
                    'name' => $stepCategory['name'],
                    'code' => $stepCategory['code'],
                    'module_code' => $stepCategory['module_code'],
                    'color' => $stepCategory['color'],
                    'count' => intval($dc[$stepCategory['id']]) ?? 0,
                ];
            }
            $res[] = [
                'id' => $value['id'],
                'name' => $value['step_category_name'],
                'count' => $count,
                'children' => $children
            ];
        }
        return $res;
    }

    /**
     * 延期单统计-按集-环节进行统计
     * @param int $projectId
     * @param  $userId
     * @return array
     */
    public function getDelayOrderCount(int $projectId ,  $userId) : array
    {
        $entityModuleId = ModuleService::getInstance()->byCode('episode','id');
//        $optionsConfig = OptionsService::getInstance()->getOptionsData('project_team_config');
//        if(empty($optionsConfig)){
//            return [];
//        }
//        $stepCategoryId = array_filter($optionsConfig, fn($item) => $item['status'] == 1);
//        $stepCategoryId = array_merge(...array_column($stepCategoryId, 'step_category_id'));
        //查看我是不是制片
        $projectMemberData = $this->checkWithForMeConfig($projectId, $userId);
        // 我能确认的环节数据
        $waitForMeToConfirmStepCategoryId = $this->canForMeConfirmStepCategoryId($projectId);
        if(empty($projectMemberData) && empty($waitForMeToConfirmStepCategoryId)){
            return [];
        }
        $where = '';
        if(!empty($projectMemberData)){
            $where = "dot.confirm_status = 'producer_confirming'";
        }


        if(!empty($waitForMeToConfirmStepCategoryId)){
            $stepCategoryIds = implode(',', $waitForMeToConfirmStepCategoryId);
            if(!empty($where)){
                $where .= ' or ';
            }
            $where .= "(delay_order_task_step_category_confirm.step_category_id in ({$stepCategoryIds}) and dot.confirm_status = 'step_category_confirming' and is_active='yes')";
        }

        $field = [
            "code",
            "id as episode_id",
            "name",
            "get_json_string(`json`, '$.episode_is_seal') as episode_is_seal",
        ];
        //
        $entityCondition = [
            "project_id" => $projectId,
            "module_id" => $entityModuleId
        ];


        $entityDbr = $this->entityModel->field($field)->where($entityCondition)->select()->toArray();

       // 如果没有制片中没有我,环节确认中也没有待我确认的
       if(!empty($where)){
           // 计算我可以确认的数据
           $dotField = ["episode_id","count( distinct dot.id ) num"];
           $dbr = $this->delayOrderTaskModel->alias('dot')->field($dotField)
               ->join(
                   'delay_order_task_step_category_confirm',
                   'delay_order_task_step_category_confirm.delay_order_task_id = dot.id',
                   'left'
               )->where([
                   'dot.project_id' => $projectId,
               ]);
           $dbr = $dbr->whereRaw($where);
       }
        $dbr = $dbr->group("dot.episode_id");
        $res = $dbr->select()->toArray();
        $result = array_column($res, 'num','episode_id');

        foreach ($entityDbr as &$value){
            $value['num'] = (int)$result[$value['episode_id']];
        }

        if(empty($entityDbr)){
            return [];
        }

        return $entityDbr;
    }

    /**
     * 我能确认的环节数据 iCanConfirmTheLinkData
     * @return array
     */
    private function canForMeConfirmStepCategoryId($projectId)
    {
        return teamones_request(
            'teamones-saas',
            'project_step_category_confirm_config/user_step_category_id_list',
            [
                "param" => [
                    "project_id" => $projectId,
                    "type" => "delay"
                ]
            ]
        )['data'] ?? [];
    }

    /**
     * @param $projectId
     * @param $userId
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function checkWithForMeConfig($projectId,$userId): array
    {
        $projectMemberData = $this->projectMemeberModel
            ->where([
                'project_id' => $projectId,
                'role_code' => 'executive_producer',
                'user_id' => $userId,
                'is_delete' => 0,
            ])->find();

        if(empty($projectMemberData)){
            return [];
        }
        return $projectMemberData->toArray();

    }
}
